﻿//-----------------------------------------------------------------------
// <copyright file="ServerSettingsDataHelper.cs" company="AFS">
// Copyright (c) AFS. All rights reserved.
//
//    This file is part of Chatbox.
//
//    Chatbox is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Lesser General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    any later version.
//
//    Chatbox is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//    GNU Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public License
//    along with Chatbox. If not, see http://www.gnu.org/copyleft/lesser.html
// </copyright>
//----------------------------------------------------------------------- 

namespace ChatBox.DomainObjects.Settings
{
    using System.IO;
    using System.Xml.Serialization;

    /// <summary>
    /// class for helper methods on settings data
    /// </summary>
    public static class ServerSettingsDataHelper
    {
        #region data

        /// <summary>
        /// Default value for the server field
        /// </summary>
        public const string DefaultServer = "http://www.everything2.com";

        /// <summary>
        /// default value for the xml tickers path
        /// </summary>
        public const string DefaultXmlTickersPath = "title/xml+interfaces+ticker";

        /// <summary>
        /// Default value for the public chat refresh interval - 10 seconds
        /// </summary>
        public const int DefaultPublicChatRefreshInterval = 10000;

        /// <summary>
        /// Max value for the public chat refresh interval - 30 seconds
        /// </summary>
        public const int MaxPublicChatRefreshInterval = 30000;

        /// <summary>
        /// Min value for the public chat refresh interval - 6 seconds
        /// </summary>
        public const int MinPublicChatRefreshInterval = 6000;

        /// <summary>
        /// Default value for the private chat refresh interval - 20 seconds
        /// </summary>
        public const int DefaultPrivateChatRefreshInterval = 20000;

        /// <summary>
        /// min value for the private chat refresh interval - 10 seconds
        /// </summary>
        public const int MinPrivateChatRefreshInterval = 10000;

        /// <summary>
        /// max value for the private chat refresh interval - 1 minute
        /// </summary>
        public const int MaxPrivateChatRefreshInterval = 60000;

        /// <summary>
        /// Default value for the other users refresh interval
        /// </summary>
        public const int DefaultOtherUsersRefreshInterval = 30000;

        /// <summary>
        /// min value for the other users refresh interval - 20 seconds
        /// </summary>
        public const int MinOtherUsersRefreshInterval = 20000;

        /// <summary>
        /// max value for the other users refresh interval - 2 minutes
        /// </summary>
        public const int MaxOtherUsersRefreshInterval = 120000;

        /// <summary>
        /// Default value for the other users refresh interval
        /// </summary>
        public const int DefaultTickersRefreshInterval = 30000;

        /// <summary>
        /// min value for the other users refresh interval - 10 seconds
        /// </summary>
        public const int MinTickersRefreshInterval = 10000;

        /// <summary>
        /// max value for the other users refresh interval - 2 minutes
        /// </summary>
        public const int MaxTickersRefreshInterval = 120000;

        /// <summary>
        /// Default value for the maximum public messages kept
        /// </summary>
        public const int DefaultMaxPublicMessagesKept = 1000;

        /// <summary>
        /// Default value for the public messages font size
        /// </summary>
        public const int DefaultPublicMessageFontSize = 16;

        /// <summary>
        /// single instance of the xml serializer for Server SettingsData
        /// </summary>
        private static XmlSerializer serverSettingsDataSerializer;

        #endregion

        #region public

        /// <summary>
        /// generate default Server settings containing the expected values
        /// </summary>
        /// <returns>the default server settings</returns>
        public static ServerSettingsData Default()
        {
            return new ServerSettingsData
            {
                Server = DefaultServer,
                XmlTickersPath = DefaultXmlTickersPath,
                PublicChatRefreshInterval = DefaultPublicChatRefreshInterval,
                PrivateChatRefreshInterval = DefaultPrivateChatRefreshInterval,
                OtherUsersRefreshInterval = DefaultOtherUsersRefreshInterval,
                TickersRefreshInterval = DefaultTickersRefreshInterval,
                MaxPublicMessagesKept = DefaultMaxPublicMessagesKept,
                UserName = string.Empty,
                Password = string.Empty,
                LastLogOnVersion = 0M
            };
        }

        /// <summary>
        /// Replace missing values in the settings with defaults
        /// </summary>
        /// <param name="serverSettings">the settings data to work with</param>
        public static void ReplaceEmptySettingsWithDefaults(ServerSettingsData serverSettings)
        {
            if (string.IsNullOrEmpty(serverSettings.Server))
            {
                serverSettings.Server = DefaultServer;
            }

            if (string.IsNullOrEmpty(serverSettings.XmlTickersFullPath()))
            {
                serverSettings.Server = DefaultXmlTickersPath;
            }

            if (serverSettings.PublicChatRefreshInterval == 0)
            {
                serverSettings.PublicChatRefreshInterval = DefaultPublicChatRefreshInterval;
            }

            if (serverSettings.PrivateChatRefreshInterval == 0)
            {
                serverSettings.PrivateChatRefreshInterval = DefaultPrivateChatRefreshInterval;
            }

            if (serverSettings.OtherUsersRefreshInterval == 0)
            {
                serverSettings.OtherUsersRefreshInterval = DefaultOtherUsersRefreshInterval;
            }

            if (serverSettings.TickersRefreshInterval == 0)
            {
                serverSettings.TickersRefreshInterval = DefaultTickersRefreshInterval;
            }

            if (serverSettings.MaxPublicMessagesKept == 0)
            {
                serverSettings.MaxPublicMessagesKept = DefaultMaxPublicMessagesKept;
            }

            // check for values out of range
            if (serverSettings.PublicChatRefreshInterval < MinPublicChatRefreshInterval)
            {
                serverSettings.PublicChatRefreshInterval = MinPublicChatRefreshInterval;
            }

            if (serverSettings.PublicChatRefreshInterval > MaxPublicChatRefreshInterval)
            {
                serverSettings.PublicChatRefreshInterval = MaxPublicChatRefreshInterval;
            }

            if (serverSettings.PrivateChatRefreshInterval < MinPrivateChatRefreshInterval)
            {
                serverSettings.PrivateChatRefreshInterval = MinPrivateChatRefreshInterval;
            }

            if (serverSettings.PrivateChatRefreshInterval > MaxPublicChatRefreshInterval)
            {
                serverSettings.PrivateChatRefreshInterval = MaxPublicChatRefreshInterval;
            }

            if (serverSettings.OtherUsersRefreshInterval < MinOtherUsersRefreshInterval)
            {
                serverSettings.OtherUsersRefreshInterval = MinOtherUsersRefreshInterval;
            }

            if (serverSettings.OtherUsersRefreshInterval > MaxOtherUsersRefreshInterval)
            {
                serverSettings.OtherUsersRefreshInterval = MaxOtherUsersRefreshInterval;
            }

            if (serverSettings.TickersRefreshInterval < MinTickersRefreshInterval)
            {
                serverSettings.TickersRefreshInterval = MinTickersRefreshInterval;
            }

            if (serverSettings.TickersRefreshInterval > MaxTickersRefreshInterval)
            {
                serverSettings.TickersRefreshInterval = MaxTickersRefreshInterval;
            }
        }

        /// <summary>
        /// Read setttings data from a stream
        /// </summary>
        /// <param name="stream">the stream to read from</param>
        /// <returns>The data read</returns>
        public static ServerSettingsData ReadFromStream(Stream stream)
        {
            XmlSerializer ser = GetDataSerializer();
            return (ServerSettingsData)ser.Deserialize(stream);
        }

        /// <summary>
        /// Write settings data to a stream
        /// </summary>
        /// <param name="data">the data to write</param>
        /// <param name="stream">the stream to write it to</param>
        public static void WriteToStream(ServerSettingsData data, Stream stream)
        {
            XmlSerializer ser = GetDataSerializer();
            ser.Serialize(stream, data);
        }

        /// <summary>
        /// Make a copy of the settings data
        /// </summary>
        /// <param name="data">the data to copy</param>
        /// <returns>a copy of the data</returns>
        public static ServerSettingsData Copy(this ServerSettingsData data)
        {
            return new ServerSettingsData
            {
                Server = data.Server,
                PublicChatRefreshInterval = data.PublicChatRefreshInterval,
                PrivateChatRefreshInterval = data.PrivateChatRefreshInterval,
                OtherUsersRefreshInterval = data.OtherUsersRefreshInterval,
                TickersRefreshInterval = data.TickersRefreshInterval,
                XmlTickersPath = data.XmlTickersPath,
                Password = data.Password,
                UserName = data.UserName,
                LastLogOnVersion = data.LastLogOnVersion,
                MaxPublicMessagesKept = data.MaxPublicMessagesKept
            };
        }

        /// <summary>
        /// Do the two settings contain the same values?
        /// </summary>
        /// <param name="data1">the first server settings</param>
        /// <param name="data2">the second server settings</param>
        /// <returns>true if they contain the same data</returns>
        public static bool SettingsSame(ServerSettingsData data1, ServerSettingsData data2)
        {
            if (data1.Server != data2.Server)
            {
                return false;
            }

            if (data1.XmlTickersPath != data2.XmlTickersPath)
            {
                return false;
            }

            if (data1.PublicChatRefreshInterval != data2.PublicChatRefreshInterval)
            {
                return false;
            }

            if (data1.PrivateChatRefreshInterval != data2.PrivateChatRefreshInterval)
            {
                return false;
            }

            if (data1.OtherUsersRefreshInterval != data2.OtherUsersRefreshInterval)
            {
                return false;
            }

            if (data1.TickersRefreshInterval != data2.TickersRefreshInterval)
            {
                return false;
            }

            if (data1.MaxPublicMessagesKept != data2.MaxPublicMessagesKept)
            {
                return false;
            }

            if (data1.UserName != data2.UserName)
            {
                return false;
            }

            if (data1.Password != data2.Password)
            {
                return false;
            }

            if (data1.LastLogOnVersion != data2.LastLogOnVersion)
            {
                return false;
            }

            return true;
        }

        #endregion

        #region private

        /// <summary>
        /// Get the XML serialiser for chat settings
        /// </summary>
        /// <returns>the xml serializer</returns>
        private static XmlSerializer GetDataSerializer()
        {
            if (serverSettingsDataSerializer == null)
            {
                serverSettingsDataSerializer = new XmlSerializer(typeof(ServerSettingsData));
            }

            return serverSettingsDataSerializer;
        }

        #endregion
    }
}
